package com.mic.yzzn.plc.common.control.datastructure;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.UUID;

import com.mic.yzzn.plc.common.instructions.basic.PLCRequestInstruction;


public class PLCMission implements Serializable
{
	/** 任务类型 */
	public static final int PLCMissionTypeWriteFireAndAck = 0,
			PLCMissionTypeWriteFireAndForget = 1,
			PLCMissionTypeReadNormal = 2,
			PLCMissionTypeReadMultiple = 3;

	
	/** 任务级别*/
	public static final int PLCMISSION_PRIORITY_RTW_0 = 0, // 实时写入队列优先级
			   PLCMISSION_PRIORITY_RTR_1 = 1, // 实时读取队列优先级
			   PLCMISSION_PRIORITY_CYR_2 = 2; // 周期读取队列优先级
	
    /** 序列化版本号 */
	private static final long serialVersionUID = 6017412904258343485L;
	/** 任务的UUID */
	private UUID missionID = UUID.randomUUID();
	/** 任务要执行的指令 */
	private ArrayList<PLCRequestInstruction> instructions = new ArrayList<PLCRequestInstruction>();
	/** 任务的类型 */
	int missionType;
	/** 任务的优先级 */
	private int priority;
	/** 最多尝试写次数 */
	private int tryToWriteTimes = 1;
	/** 最多尝试读次数 */
	private int tryToReadTimes = 1;
	
	
	// 初始化方法
	@SuppressWarnings("unused")
	private PLCMission()
	{
		
	}
	
	public PLCMission(int type, int priority)
	{
		this.missionType = type;
		this.priority = priority;
	}
	
	private boolean isQualifiedInstructions(ArrayList<PLCRequestInstruction> instructions, boolean isRead)
	{
		for (PLCRequestInstruction ins : instructions)
		{
			// 检测指令是否是想要的（读/写）类型
			boolean isRight = (isRead? ins.isRead() : ins.isWrite());
			
			// 如果不是合格的指令则返回不合格
			if (!isRight)
			{
				return false;
			}
		}
		
		return true;
	}
	
	// Getter
	public UUID getMissionID()
	{
		return missionID;
	}
	
	public ArrayList<PLCRequestInstruction> getInstructions()
	{
		return instructions;
	}
	
	public int getMissionType()
	{
		return missionType;
	}
	
	public int getPriority()
	{
		return priority;
	}

    public int getTryToWriteTimes()
    {
        return tryToWriteTimes;
    }
    
    public int getTryToReadTimes()
	{
		return tryToReadTimes;
	}

    // Setter
	public void setInstructions(ArrayList<PLCRequestInstruction> instructions) throws IllegalArgumentException
	{
		if (!isQualifiedInstructions(instructions, (priority != PLCMISSION_PRIORITY_RTW_0)))
		{
			throw new IllegalArgumentException("there are some instructions in \"instructions\" that don't fit the request of mission's type");
		}
		
		this.instructions = instructions;
	}
	
	public void setMissionType(int missionType)
	{
		this.missionType = missionType;
	}
	
	public void setPriority(int priority)
	{
		this.priority = priority;
	}

    public void setTryToWriteTimes(int tryToWriteTimes)
    {
		if (tryToWriteTimes >= 0)
		{
			this.tryToWriteTimes = tryToWriteTimes;
		}
		else
		{
			this.tryToWriteTimes = 1;
		}
    }
    
    public void setTryToReadTimes(int tryToReadTimes)
	{
    	if (tryToReadTimes >= 0)
		{
			this.tryToReadTimes = tryToReadTimes;
		}
		else
		{
			this.tryToReadTimes = 1;
		}
	}
}
